home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / TUT10NEW.ZIP / TUT10.CPP < prev    next >
C/C++ Source or Header  |  1995-02-02  |  15KB  |  391 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //                                                                         //
  3. // TUTPROG10.CPP - VGA Trainer Program 10 (in Turbo C++ 3.0)               //
  4. //                                                                         //
  5. // "The VGA Trainer Program" was originally written by Denthor of          //
  6. // Asphyxia.  It contained some nice pascal source and documentation.  But //
  7. // then Snowman came along.  He saw disorder, he saw inefficiency, he      //
  8. // saw PASCAL.  Denthor couldn't stop Snowman, so Snowman went on to       //
  9. // convert tha pascal source to C++.  ...and the people were happy.        //
  10. //                                                                         //
  11. // Program Notes : This program presents the basics of Chain-4.            //
  12. //                                                                         //
  13. //                 Just for reference, this is the command line I use:     //
  14. //                                                                         //
  15. //                    tcc -mc -a -G -2 -O tut10.cpp                        //
  16. //                                                                         //
  17. //                 The way things are set up, there is no need to compile  //
  18. //                 or link tut10.cpp and gfx2.cpp seperately.              //
  19. //                                                                         //
  20. // Author        : Grant Smith (Denthor) - denthor@beastie.cs.und.ac.za    //
  21. // Translator    : Christopher G. Mann   - r3cgm@dax.cc.uakron.edu         //
  22. //                                                                         //
  23. // Last Modified : February 1, 1995                                        //
  24. //                                                                         //
  25. /////////////////////////////////////////////////////////////////////////////
  26.  
  27. //               //
  28. // INCLUDE FILES //
  29. //               //
  30.  
  31.   #include <conio.h>
  32.                            // clrscr(), getch(), kbhit()
  33.   #include <iostream.h>
  34.                            // cout
  35.   #include <stdlib.h>
  36.                            // rand()
  37.   #include "gfx2.cpp"
  38.                            // SetText(), WaitRetrace(), Pal::
  39.  
  40. //          //
  41. // TYPEDEFS //
  42. //          //
  43.  
  44.   // unsigned chars are sissy
  45.   typedef unsigned char byte;
  46.   typedef unsigned int  word;
  47.  
  48. //           //
  49. // CONSTANTS //
  50. //           //
  51.  
  52.   const byte BIT[897] = {
  53.        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33,2,151,5,149,6,148,7,147,8,49,2,
  54.        95,8,49,4,93,9,49,3,93,4,2,3,49,4,92,4,3,3,48,4,92,4,3,4,48,4,91,4,4,
  55.        3,48,4,92,4,3,4,48,3,58,2,32,4,4,4,47,4,57,3,31,4,5,3,48,3,57,4,30,4,
  56.        5,4,47,3,57,5,29,4,6,4,46,4,57,4,29,4,7,3,47,3,58,2,30,4,7,4,46,4,90,
  57.        4,7,4,46,3,90,4,8,4,27,2,16,3,90,4,8,9,22,3,16,3,89,4,5,13,8,6,8,3,15,
  58.        3,90,4,2,15,6,10,6,3,16,3,6,1,21,1,9,2,7,1,21,6,14,18,9,5,2,4,5,4,1,4,
  59.        10,3,4,5,10,2,7,3,8,2,5,3,9,3,7,8,13,13,1,4,9,4,5,3,5,3,1,6,9,3,3,6,9,
  60.        4,5,4,8,3,3,4,9,3,6,9,11,10,6,4,8,4,6,3,4,11,8,3,2,7,9,5,4,4,9,3,2,4,
  61.        9,3,6,4,4,2,8,10,9,4,7,4,6,3,5,5,3,3,8,3,1,8,8,5,4,5,8,3,3,3,9,4,5,4,
  62.        5,2,5,10,12,4,7,3,5,5,4,5,4,3,7,3,1,4,1,3,9,4,5,4,9,3,2,3,10,3,6,3,5,
  63.        3,4,10,13,3,8,3,2,7,5,4,5,3,7,7,1,3,9,4,5,5,9,3,1,3,10,3,6,3,5,4,4,5,
  64.        1,4,12,4,8,3,2,5,6,4,5,4,6,6,2,4,8,4,5,5,10,6,10,4,5,4,5,3,5,2,3,4,13,
  65.        4,8,3,3,1,9,3,6,3,7,5,3,3,5,1,3,3,5,5,4,2,5,5,11,3,6,3,5,4,10,3,14,4,
  66.        8,3,12,3,6,4,6,5,3,3,5,2,2,4,4,6,4,2,5,5,6,1,3,4,5,3,6,3,10,4,14,4,5,
  67.        1,2,4,11,3,6,3,7,5,3,3,4,3,1,4,4,6,4,3,5,4,6,2,3,3,6,3,5,4,9,4,15,3,5,
  68.        2,3,4,9,3,6,4,7,4,3,3,5,2,2,3,4,7,3,3,6,3,6,3,2,4,5,4,5,3,10,3,15,4,4,
  69.        3,4,3,9,3,6,3,7,4,4,3,4,3,1,4,3,3,1,3,3,3,6,4,6,2,3,3,6,3,5,4,9,4,15,
  70.        4,4,3,4,4,7,3,6,4,7,4,3,3,4,3,2,3,3,3,2,3,2,4,5,5,5,3,2,4,6,3,5,4,8,4,
  71.        16,4,4,2,6,3,7,3,5,4,7,4,4,3,3,3,3,8,2,3,2,4,5,6,4,3,3,3,7,3,4,5,8,4,
  72.        16,4,4,2,6,3,6,3,5,4,8,3,5,8,3,9,2,3,1,4,6,6,3,3,4,3,7,3,3,6,7,4,17,4,
  73.        4,3,5,3,6,3,4,4,9,3,5,8,3,7,3,8,6,3,1,4,1,4,3,4,7,3,2,3,1,3,7,4,17,4,
  74.        4,3,5,3,5,11,9,3,6,7,4,6,4,7,6,3,2,8,4,3,8,7,2,3,6,4,18,3,5,4,3,4,5,
  75.        10,10,3,6,6,6,4,4,6,7,3,4,6,5,3,8,7,2,4,4,4,19,3,5,10,5,3,1,6,11,3,7,
  76.        3,16,5,7,4,4,5,6,3,8,6,3,5,3,4,19,3,6,9,5,3,18,2,25,5,9,3,6,3,7,2,10,
  77.        3,6,4,3,3,20,3,8,5,6,3,44,6,10,2,39,3,3,2,22,2,19,3,43,7,101,3,42,8,
  78.        102,3,41,4,1,4,101,4,39,5,2,3,102,3,39,4,4,3,102,3,38,4,4,4,101,3,38,
  79.        4,5,3,102,3,37,4,5,4,101,4,36,4,6,3,102,3,37,3,6,4,102,3,36,4,6,3,102,
  80.        3,37,3,6,3,103,3,37,3,5,4,102,4,37,3,4,4,103,3,38,10,104,3,38,9,105,2,
  81.        40,7,106,2,41,4,0};
  82.  
  83. //                     //
  84. // FUNCTION PROTOTYPES //
  85. //                     //
  86.  
  87.   void InitChain4();
  88.   void C4PutPixel(word X, word Y, byte Col);
  89.   void Plane     (byte Which);
  90.   void MoveTo    (word X, word Y);
  91.   void Putpic    (int x, int y);
  92.   void Play      ();
  93.  
  94. //                  //
  95. // GLOBAL VARIABLES //
  96. //                  //
  97.  
  98.   // Just for fun, change this to "const byte SIZE = 80" and try to run
  99.   // the program.  It is generally a good programming practice to use
  100.   // contant variables when you know that the values should not change.
  101.   // However, this program uses lots of assembler.  I guess that a constant
  102.   // byte is stored differently than just a normal byte.  Go figure!  :)
  103.  
  104.   byte SIZE = 80;      // Size =  40 = 1 across, 4 down
  105.                        // Size =  80 = 2 across, 2 down
  106.                        // Size = 160 = 4 across, 1 down
  107.  
  108.  
  109. ///////////////////////////////////////////////////////////////////////////////
  110. //                                                                           //
  111. //                                MAIN FUNCTION                              //
  112. //                                                                           //
  113. ///////////////////////////////////////////////////////////////////////////////
  114.  
  115. void main() {
  116.  
  117.   clrscr();
  118.   cout
  119.     << "Hello there! Here is the tenth tutorial, on Chain-4! You will notice\n"
  120.     << "that there are two files here : one contains all of our graphics\n"
  121.     << "based routines, and one is the demo program.\n\n"
  122.     << "In the demo program, we will do the necessary port stuff to get into\n"
  123.     << "Chain-4. Once in Chain-4 mode, I will put down text saying ASPHYXIA\n"
  124.     << "over the entire screen. After a key is pressed, the viewport will\n"
  125.     << "bounce around, displaying the entire Chain-4 screen. The program will\n"
  126.     << "end when [ESC] is pressed. The code here is really basic (except for\n"
  127.     << "those port values), and should be very easy to understand.\n\n";
  128.  
  129.   cout
  130.     << "Yo, Snowman here.  Frankly I'm tired of just converting these\n"
  131.     << "bloody tutorials!  :)  I am going to start doing some ""creative""\n"
  132.     << "things in these programs.  The first deviant thing I'm doing is\n"
  133.     << "flipping Denthor's snazzy logo so that <Asphyxia> is reversed.\n"
  134.     << "Hey, we all got to break out and have fun sometime, right?  :)\n\n";
  135.   cout << "Hit any key to continue ...";
  136.   getch();
  137.  
  138.   InitChain4();
  139.   Play();
  140.  
  141.   SetText();
  142.   cout
  143.     << "All done. This concludes the tenth sample program in the ASPHYXIA\n"
  144.     << "Training series. You may reach DENTHOR under the names of GRANT\n"
  145.     << "SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS. I am also an avid\n"
  146.     << "Connectix BBS user, and occasionally read RSAProg. E-mail me at :\n"
  147.     << "    smith9@batis.bis.und.ac.za\n"
  148.     << "The numbers are available in the main text. You may also write to me at:\n"
  149.     << "             Grant Smith\n"
  150.     << "             P.O. Box 270\n"
  151.     << "             Kloof\n"
  152.     << "             3640\n"
  153.     << "             Natal\n"
  154.     << "             South Africa\n"
  155.     << "I hope to hear from you soon!\n\n";
  156.   cout << "Hit any key to exit ...";
  157.   getch();
  158.  
  159. }
  160.  
  161.  
  162. /////////////////////////////////////////////////////////////////////////////
  163. //                                                                         //
  164. // InitChain4() - This function gets you into Chain 4 mode.                //
  165. //                Note: As soon as I find documentation, this function     //
  166. //                will be better documented.  - Snowman                    //
  167. //                                                                         //
  168. /////////////////////////////////////////////////////////////////////////////
  169.  
  170. void InitChain4() {
  171.  
  172.   asm {
  173.     mov    ax, 0x13      // routine 13 = MCGA mode
  174.     int    0x10          // do it!
  175.     mov    dx, 0x3C4     // Port 0x3C4 = Sequencer Address Register
  176.     mov    al, 4         // Index 4 = memory mode
  177.     out    dx, al        // send it
  178.     inc    dx            // Port 0x3C5 ... here we set the mem mode
  179.     in     al, dx
  180.     and    al, not 0x08
  181.     or     al, 0x04
  182.     out    dx, al
  183.     mov    dx, 0x3CE
  184.     mov    al, 5
  185.     out    dx, al
  186.     inc    dx
  187.     in     al, dx
  188.     and    al, not 0x10
  189.     out    dx, al
  190.     dec    dx
  191.     mov    al, 6
  192.     out    dx, al
  193.     inc    dx
  194.     in     al, dx
  195.     and    al, not 0x02
  196.     out    dx, al
  197.     mov    dx, 0x3C4
  198.     mov    ax, (0x0F shl 8) + 2
  199.     out    dx, ax
  200.     mov    ax, 0xA000
  201.     mov    es, ax
  202.     sub    di, di
  203.     mov    ax, 0x0000    // 0x8080
  204.     mov    cx, 32768
  205.     cld
  206.     rep    stosw         // Clear garbage off the screen ...
  207.  
  208.     mov    dx, 0x3D4
  209.     mov    al, 0x14
  210.     out    dx, al
  211.     inc    dx
  212.     in     al, dx
  213.     and    al, not 0x40
  214.     out    dx, al
  215.     dec    dx
  216.     mov    al, 0x17
  217.     out    dx, al
  218.     inc    dx
  219.     in     al, dx
  220.     or     al, 0x40
  221.     out    dx, al
  222.  
  223.     mov    dx, 0x3D4
  224.     mov    al, 0x13
  225.     out    dx, al
  226.     inc    dx
  227.     mov    al, [SIZE]    // Size * 8 = Pixels across. Only 320 are visible
  228.     out    dx, al
  229.   }
  230. }
  231.  
  232.  
  233. /////////////////////////////////////////////////////////////////////////////
  234. //                                                                         //
  235. // C4PutPixel() - This puts a pixel on the chain 4 screen.                 //
  236. //                Note: As soon as I find documentation, this function     //
  237. //                will be better documented.  - Snowman                    //
  238. //                                                                         //
  239. /////////////////////////////////////////////////////////////////////////////
  240.  
  241. void C4PutPixel(word X, word Y, byte Col) {
  242.  
  243.   asm {
  244.     mov    ax,[Y]
  245.     xor    bx,bx
  246.     mov    bl,[SIZE]
  247.     imul   bx
  248.     shl    ax,1
  249.     mov    bx,ax
  250.     mov    ax, [X]
  251.     mov    cx, ax
  252.     shr    ax, 2
  253.     add    bx, ax
  254.     and    cx, 00000011b
  255.     mov    ah, 1
  256.     shl    ah, cl
  257.     mov    dx, 0x3C4             // Sequencer Register
  258.     mov    al, 2                 // Map Mask Index
  259.     out    dx, ax
  260.     mov    ax, 0xA000
  261.     mov    es, ax
  262.     mov    al, [Col]
  263.     mov    es: [bx], al
  264.   }
  265. }
  266.  
  267.  
  268. /////////////////////////////////////////////////////////////////////////////
  269. //                                                                         //
  270. // Plane() - This sets the plane to write to in Chain 4.                   //
  271. //                Note: As soon as I find documentation, this function     //
  272. //                will be better documented.  - Snowman                    //
  273. //                                                                         //
  274. /////////////////////////////////////////////////////////////////////////////
  275.  
  276. void Plane (byte Which) {
  277.  
  278.   asm {
  279.     mov    al, 0x2
  280.     mov    ah, 1
  281.     mov    cl, [Which]
  282.     shl    ah, cl
  283.     mov    dx, 0x3C4              // Sequencer Register
  284.     out    dx, ax
  285.   }
  286. }
  287.  
  288.  
  289. /////////////////////////////////////////////////////////////////////////////
  290. //                                                                         //
  291. // MoveTo() - This moves to position X*4 on a chain 4 screen.              //
  292. //                Note: As soon as I find documentation, this function     //
  293. //                will be better documented.  - Snowman                    //
  294. //                                                                         //
  295. /////////////////////////////////////////////////////////////////////////////
  296.  
  297. void MoveTo (word X, word Y) {
  298.  
  299.   word O = Y*SIZE*2+X;
  300.  
  301.   asm {
  302.     mov    bx, [O]
  303.     mov    ah, bh
  304.     mov    al, 0x0C
  305.  
  306.     mov    dx, 0x3D4
  307.     out    dx, ax
  308.  
  309.     mov    ah, bl
  310.     mov    al, 0x0D
  311.     mov    dx, 0x3D4
  312.     out    dx, ax
  313.   }
  314. }
  315.  
  316.  
  317. /////////////////////////////////////////////////////////////////////////////
  318. //                                                                         //
  319. // Putpic() - This puts the picture at coordinates x,y on the chain-4      //
  320. //            screen.                                                      //
  321. //                                                                         //
  322. /////////////////////////////////////////////////////////////////////////////
  323.  
  324. void Putpic (int x, int y) {
  325.  
  326.   int loop1, loop2, cur=0;
  327.   word depth = 1;
  328.  
  329.   // for every element of the picture data...
  330.   for (loop1=0; loop1<897; loop1++) {
  331.     for (loop2=0; loop2<BIT[loop1]; loop2++) {
  332.       // read the tut10.txt file for more information on what this does
  333.       if (cur != 0)
  334.         // take out the "155-" to make the logo face the right direction
  335.         C4PutPixel(155-(depth % 155)+x, (depth / 155)+y,(depth / 155));
  336.       depth++;
  337.     }
  338.     cur = (cur+1) % 2;
  339.   }
  340. }
  341.  
  342.  
  343. /////////////////////////////////////////////////////////////////////////////
  344. //                                                                         //
  345. // Play() - The function that does it all...                               //
  346. //                                                                         //
  347. /////////////////////////////////////////////////////////////////////////////
  348.  
  349. void Play() {
  350.  
  351.   int loop1, loop2, xpos, ypos, xdir, ydir;
  352.   Pal PicPal[64];
  353.   char ch = 1;
  354.  
  355.   // This sets up the pallette for the picture
  356.   for (loop1=1; loop1<63; loop1++) {
  357.     PicPal[loop1].PalSet(loop1,0,62-loop1);
  358.     PicPal[loop1].PalPut(loop1);
  359.   }
  360.  
  361.   // This moves the view to the top left hand corner
  362.   MoveTo(0,0);
  363.  
  364.   // This places the picture all over the chain-4 screen
  365.   for (loop1=0; loop1<4; loop1++)
  366.     for (loop2=0; loop2<6; loop2++)
  367.       Putpic(loop1*160, loop2*66);
  368.   getch();
  369.  
  370.   // Random start positions/movements for the view
  371.   xpos = (rand() %  78) + 1;
  372.   ypos = (rand() % 198) + 1;
  373.   xdir = 1;
  374.   ydir = 1;
  375.  
  376.   // Main loop (move around the Chain-4 Screen)
  377.   do {
  378.     if (kbhit()) ch = getch();
  379.     MoveTo(xpos, ypos);
  380.     // Take this out and watch the screen go crazy!
  381.     WaitRetrace();
  382.     xpos += xdir;
  383.     ypos += ydir;
  384.     // Hit a boundry, change direction
  385.     if ((xpos >  79) || (xpos < 1)) xdir *= -1;
  386.     if ((ypos > 199) || (ypos < 1)) ydir *= -1;
  387.     if (ch == 0) ch = getch();
  388.   } while (ch != 27); // if the escape code was 27 (escape key) then exit
  389.  
  390. }
  391.